/////////////////////////////////////////////////////////////////////////////
// Name:        xmlparser.cpp
// Purpose:     XML parser utilities
// Author:      Julian Smart
// Modified by:
// Created:     2008-11-18
// RCS-ID:      $Id$
// Copyright:   (c) Julian Smart
// Licence:     New BSD License
/////////////////////////////////////////////////////////////////////////////

#include "wx/wx.h"

#include "wx/xrc/xmlres.h"

#include "xmlutils/xmlparser.h"

wxXmlNode *wxXMLParser::GetParamNode(wxXmlNode *node, const wxString& param)
{
    wxXmlNode *n = node->GetChildren();
    
    while (n)
    {
        if (n->GetType() == wxXML_ELEMENT_NODE && n->GetName() == param)
            return n;
        n = n->GetNext();
    }
    return NULL;
}

wxString wxXMLParser::GetNodeContent(wxXmlNode *node)
{
    wxXmlNode *n = node;
    if (n == NULL) return wxEmptyString;
    n = n->GetChildren();
    
    while (n)
    {
        if (n->GetType() == wxXML_TEXT_NODE ||
            n->GetType() == wxXML_CDATA_SECTION_NODE)
            return n->GetContent();
        n = n->GetNext();
    }
    return wxEmptyString;
}

wxString wxXMLParser::GetParamValue(wxXmlNode *node, const wxString& param)
{
    if (param.IsEmpty())
        return GetNodeContent(node);
    else
        return GetNodeContent(GetParamNode(node, param));
}

bool wxXMLParser::HasParam(wxXmlNode *node, const wxString& param)
{
    return (GetParamNode(node, param) != NULL);
}

wxString wxXMLParser::GetText(wxXmlNode *node, const wxString& param)
{
    wxString str1(GetParamValue(node, param));
    wxString str2;
    const wxChar *dt;

    // wxChar amp_char;
    // amp_char = wxT('_');
    
    for (dt = str1.c_str(); *dt; dt++)
    {
#if 0
        // Remap amp_char to &, map double amp_char to amp_char (for things
        // like "&File..." -- this is illegal in XML, so we use "_File..."):
        if (*dt == amp_char)
        {
            if ( *(++dt) == amp_char )
                str2 << amp_char;
            else
                str2 << wxT('&') << *dt;
        }
#endif
        // Remap \n to CR, \r to LF, \t to TAB:
        if (*dt == wxT('\\'))
            switch (*(++dt))
        {
                case wxT('n') : str2 << wxT('\n'); break;
                case wxT('t') : str2 << wxT('\t'); break;
                case wxT('r') : str2 << wxT('\r'); break;
                default       : str2 << wxT('\\') << *dt; break;
        }
        else str2 << *dt;
    }
    
    return str2;
}

/// Find all strings with the given tag
wxArrayString wxXMLParser::FindValues(wxXmlNode* node, const wxString& tag)
{
    wxArrayString values;

    wxXmlNode* itemChild = node->GetChildren();
    while (itemChild)
    {
        if (itemChild->GetName() == tag)
        {
            wxString text(GetText(itemChild, wxEmptyString));
            if (!text.IsEmpty())
                values.Add(text);
        }

        itemChild = itemChild->GetNext();
    }

    return values;
}
